package com.example.othree.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.othree.entity.TowerOzone;
import com.example.othree.entity.TowerOzoneGradientObservations;
import com.example.othree.mapper.TowerOzoneGradientObservationsMapper;
import com.example.othree.mapper.TowerOzoneMapper;
import com.example.othree.service.TowerOzoneService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class TowerOzoneServiceImpl extends ServiceImpl<TowerOzoneMapper, TowerOzone> implements TowerOzoneService {
    @Resource
    @Autowired
    TowerOzoneMapper towerOzoneMapper;

    @Autowired
    TowerOzoneGradientObservationsMapper towerOzoneGradientObservationsMapper;

    // 站点和对应固定高度的映射
    private static final Map<String, List<Integer>> STATION_HEIGHT_MAP = new HashMap<>();
    static {
        STATION_HEIGHT_MAP.put("邢台", Arrays.asList(4, 10, 16)); // 邢台的固定高度
        STATION_HEIGHT_MAP.put("衡水", Arrays.asList(4, 10, 16, 32, 53)); // 衡水的固定高度
    }

    public Map<String, Object> getTowerOzoneData(String station, String time){

        System.out.println(station);
        // 获取该站点的固定高度列表
        List<Integer> fixedHeights = STATION_HEIGHT_MAP.get(station);
        if (fixedHeights == null) {
            throw new IllegalArgumentException("未知站点: " + station);
        }

        //查询数据库中的梯度风数据
        List<TowerOzone> dataList11 = towerOzoneMapper.selectList(new QueryWrapper<TowerOzone>()
                .like("PointName", station) //匹配站点名
                .eq("time", time));

        //查询数据库中的气象数据
        List<TowerOzoneGradientObservations> dataList12 = towerOzoneGradientObservationsMapper.selectList(new QueryWrapper<TowerOzoneGradientObservations>()
                .like("PointName", station) //匹配站点名
                .eq("time", time));

        //将数据按高度分组(风向)
        Map<Integer, TowerOzone> heightDataMap1 = dataList11.stream()
                .filter(data -> data.getHeight() != null) //过滤掉高度为null的数据
                .collect(Collectors.toMap(TowerOzone::getHeight, Function.identity()));

        //将数据按高度分组(气象)
        Map<Integer, TowerOzoneGradientObservations> heightDataMap2 = dataList12.stream()
                .filter(data -> data.getHeight() != null) //过滤掉高度为null的数据
                .collect(Collectors.toMap(TowerOzoneGradientObservations::getHeight, Function.identity()));

        //初始化结果
        Map<String, Object> result = new HashMap<>();
        result.put("o3", new ArrayList<>(Collections.nCopies(fixedHeights.size(), null)));
        result.put("no2", new ArrayList<>(Collections.nCopies(fixedHeights.size(), null)));
        result.put("so2", new ArrayList<>(Collections.nCopies(fixedHeights.size(), null)));
        result.put("co", new ArrayList<>(Collections.nCopies(fixedHeights.size(), null)));
        result.put("rh", new ArrayList<>(Collections.nCopies(fixedHeights.size(), null)));
        result.put("temp", new ArrayList<>(Collections.nCopies(fixedHeights.size(), null)));
        result.put("wind1", new ArrayList<>(Collections.nCopies(fixedHeights.size(), null)));
        result.put("wdir1", new ArrayList<>(Collections.nCopies(fixedHeights.size(), null)));
        result.put("wind2", new ArrayList<>(Collections.nCopies(fixedHeights.size(), null)));
        result.put("wdir2", new ArrayList<>(Collections.nCopies(fixedHeights.size(), null)));
        result.put("ww2", new ArrayList<>(Collections.nCopies(fixedHeights.size(), null)));
        result.put("time", time.toString());
        result.put("Station", station);

        // 填充数据
        for (int i = 0; i < fixedHeights.size(); i++) {
            int height = fixedHeights.get(i); // 获取固定高度
            TowerOzone data1 = heightDataMap1.get(height);
            TowerOzoneGradientObservations data2 = heightDataMap2.get(height);
            if (data1 != null) {

                ((List<Double>) result.get("rh")).set(i, data1.getRh());
                ((List<Double>) result.get("temp")).set(i, data1.getTemp());
                ((List<Double>) result.get("wind1")).set(i, data1.getWind1());
                ((List<Double>) result.get("wdir1")).set(i, data1.getWdir1());
                ((List<Double>) result.get("wind2")).set(i, data1.getWind2());
                ((List<Double>) result.get("wdir2")).set(i, data1.getWdir2());
                ((List<Double>) result.get("ww2")).set(i, data1.getWdir2());
            }
            if (data2 != null) {
                ((List<Double>) result.get("o3")).set(i, data2.getO3());
                ((List<Double>) result.get("no2")).set(i, data2.getNo2());
                ((List<Double>) result.get("so2")).set(i, data2.getSo2());
                ((List<Double>) result.get("co")).set(i, data2.getCo());
            }
        }

        return result;
    }

    /**
     * 接口2
     */


    public Map<String, Object> getAirQualityData(LocalDateTime startTime, LocalDateTime endTime, String stationName, String element, String queryType) {
        System.out.println("查询气象数据");
        List<Map<String, Object>> dataList;

        // 根据查询类型获取原始数据
        switch (queryType) {
            case "minute":
                dataList = getMinuteData(startTime, endTime, stationName, element);
                break;
            case "hourly":
                dataList = getHourlyAverageData(startTime, endTime, stationName, element);
                break;
            case "8hour":
                dataList = get8HourAverageData(startTime, endTime, stationName, element);
                break;
            case "daily":
                dataList = getDailyAverageData(startTime, endTime, stationName, element);
                break;
            default:
                throw new IllegalArgumentException("不支持的查询类型: " + queryType);
        }

        // 处理dataList为空的情况
        if (dataList == null) {
            dataList = Collections.emptyList();
        }


        // 获取站点的高度列表
        List<Integer> heights = STATION_HEIGHT_MAP.get(stationName);
        if (heights == null) {
            throw new IllegalArgumentException("未知站点: " + stationName);
        }

        // 将数据按时间分组
        Map<String, List<Map<String, Object>>> groupedByTime = dataList.stream()
                .collect(Collectors.groupingBy(data -> (String) data.get("time")));

        // 转换数据格式
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map.Entry<String, List<Map<String, Object>>> entry : groupedByTime.entrySet()) {
            String time = entry.getKey();
            List<Map<String, Object>> timeData = entry.getValue();

            // 初始化每个时间点的数据
            Map<String, Object> item = new HashMap<>();
            item.put("time", time);
            item.put("avgValue", new ArrayList<>(Collections.nCopies(heights.size(), null)));

            // 填充数据
            for (Map<String, Object> data : timeData) {
                String pointName = (String) data.get("pointName");
                // 检查avgValue是否为null
                Object avgValueObj = data.get("avgValue");
                if (avgValueObj == null) {
                    continue; // 跳过该条数据或设置默认值
                }
                double avgValue = (double) data.get("avgValue");

                // 解析高度
                int height = Integer.parseInt(pointName.replaceAll("[^0-9]", "")); // 提取高度数字

                // 找到高度在固定高度列表中的索引
                int heightIndex = heights.indexOf(height);
                if (heightIndex != -1) {
                    // 将数据放入对应位置
                    ((List<Double>) item.get("avgValue")).set(heightIndex, avgValue);
                }
            }

            result.add(item);
        }
        // 构建最终返回结果
        Map<String, Object> resultData = new HashMap<>();
        resultData.put("Station", stationName);
        resultData.put("select_Time", Arrays.asList(
                startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
                endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
        ));
        resultData.put("select_leixing", queryType);
        resultData.put("high", heights);
        resultData.put("result", result);

        return resultData;
    }
    // 分钟数据查询(气象)
    private List<Map<String, Object>> getMinuteData(LocalDateTime startTime, LocalDateTime endTime, String stationName, String element) {
        return towerOzoneGradientObservationsMapper.getMinuteData(startTime, endTime, stationName, element);
    }

    /**
     * 获取逐小时平均数据(气象)
     */
    public List<Map<String, Object>> getHourlyAverageData(LocalDateTime startTime, LocalDateTime endTime, String stationName, String element) {
        return towerOzoneGradientObservationsMapper.getHourlyAverageData(startTime, endTime, stationName,element);
    }

    /**
     * 获取日平均数据(气象)
     */
    public List<Map<String, Object>> getDailyAverageData(LocalDateTime startTime, LocalDateTime endTime, String stationName, String element) {
        return towerOzoneGradientObservationsMapper.getDailyAverageData(startTime, endTime, stationName, element);
    }

    /**
     * 获取 8 小时滑动平均数据(气象)
     */
    private List<Map<String, Object>> get8HourAverageData(LocalDateTime startTime, LocalDateTime endTime, String stationName, String element) {

        List<Map<String, Object>> result = new ArrayList<>();

        for(LocalDateTime i = startTime.minusHours(7); i.isBefore(endTime.minusHours(6)); i = i.plusHours(1)){
            List<Map<String, Object>> data = towerOzoneGradientObservationsMapper.getHourly8AverageData(i,i.plusHours(8),stationName,element);
            LocalDateTime time = i.plusHours(8);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00:00");
            String timeStr = time.format(formatter); // 将 LocalDateTime 转换为字符串
            for (Map<String, Object> item : data) {
                item.put("time", timeStr);
            }

//            System.out.println(data);
            result.addAll(data);
        }
        return result;
    }

    public Map<String, Object> getWindData(LocalDateTime startTime, LocalDateTime endTime, String stationName, String element, String queryType) {
        System.out.println("查询风向数据");
        List<Map<String, Object>> dataList;

        // 根据查询类型获取原始数据
        switch (queryType) {
            case "minute":
                dataList = getMinuteWindData(startTime, endTime, stationName, element);
                break;
            case "hourly":
                dataList = getHourlyAverageWindData(startTime, endTime, stationName, element);
                break;
            case "8hour":
                dataList = get8HourAverageWindData(startTime, endTime, stationName, element);
                break;
            case "daily":
                dataList = getDailyAverageWindData(startTime, endTime, stationName, element);
                break;
            default:
                throw new IllegalArgumentException("不支持的查询类型: " + queryType);
        }

        // 处理dataList为空的情况
        if (dataList == null) {
            dataList = Collections.emptyList();
        }

        // 获取站点的高度列表
        List<Integer> heights = STATION_HEIGHT_MAP.get(stationName);
        if (heights == null) {
            throw new IllegalArgumentException("未知站点: " + stationName);
        }

        // 将数据按时间分组
        Map<String, List<Map<String, Object>>> groupedByTime = dataList.stream()
                .collect(Collectors.groupingBy(data -> (String) data.get("time")));

        // 转换数据格式
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map.Entry<String, List<Map<String, Object>>> entry : groupedByTime.entrySet()) {
            String time = entry.getKey();
            List<Map<String, Object>> timeData = entry.getValue();

            // 初始化每个时间点的数据
            Map<String, Object> item = new HashMap<>();
            item.put("time", time);
            item.put("avgValue", new ArrayList<>(Collections.nCopies(heights.size(), null)));

            // 填充数据
            for (Map<String, Object> data : timeData) {
                String pointName = (String) data.get("pointName");
                // 检查avgValue是否为null
                Object avgValueObj = data.get("avgValue");
                if (avgValueObj == null) {
                    continue; // 跳过该条数据或设置默认值
                }
                double avgValue = (double) data.get("avgValue");

                // 解析高度
                int height = Integer.parseInt(pointName.replaceAll("[^0-9]", "")); // 提取高度数字

                // 找到高度在固定高度列表中的索引
                int heightIndex = heights.indexOf(height);
                if (heightIndex != -1) {
                    // 将数据放入对应位置
                    ((List<Double>) item.get("avgValue")).set(heightIndex, avgValue);
                }
            }

            result.add(item);
        }
        // 构建最终返回结果
        Map<String, Object> resultData = new HashMap<>();
        resultData.put("Station", stationName);
        resultData.put("select_Time", Arrays.asList(
                startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
                endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
        ));
        resultData.put("select_leixing", queryType);
        resultData.put("high", heights);
        resultData.put("result", result);

        return resultData;
    }
    // 分钟数据查询(梯度风)
        private List<Map<String, Object>> getMinuteWindData(LocalDateTime startTime, LocalDateTime endTime, String stationName, String element) {
            return towerOzoneMapper.getMinuteWindData(startTime, endTime, stationName, element);
        }


        /**
         * 获取逐小时平均数据(梯度风)
         */
    public List<Map<String, Object>> getHourlyAverageWindData(LocalDateTime startTime, LocalDateTime endTime, String stationName, String element) {
        return towerOzoneMapper.getHourlyAverageWindData(startTime, endTime, stationName,element);
    }

    /**
     * 获取日平均数据(梯度风)
     */
    public List<Map<String, Object>> getDailyAverageWindData(LocalDateTime startTime, LocalDateTime endTime, String stationName, String element) {
        return towerOzoneMapper.getDailyAverageWindData(startTime, endTime, stationName, element);
    }

    /**
     * 获取 8 小时滑动平均数据(梯度风)
     */
    private List<Map<String, Object>> get8HourAverageWindData(LocalDateTime startTime, LocalDateTime endTime, String stationName, String element) {
        List<Map<String, Object>> result = new ArrayList<>();

        for(LocalDateTime i = startTime.minusHours(7); i.isBefore(endTime.minusHours(6)); i = i.plusHours(1)){
            List<Map<String, Object>> data = towerOzoneMapper.getHourly8AverageWindData(i,i.plusHours(8),stationName,element);
            LocalDateTime time = i.plusHours(8);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00:00");
            String timeStr = time.format(formatter); // 将 LocalDateTime 转换为字符串
            for (Map<String, Object> item : data) {
                item.put("time", timeStr);
            }

//            System.out.println(data);
            result.addAll(data);
        }
        return result;
    }

    /**
     * 接口三
     */
    public Map<String, Object> getAirQualityAllData(LocalDateTime startTime, LocalDateTime endTime, String stationName, String queryType) {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> dataList;

        // 根据查询类型获取原始数据
        switch (queryType) {
            case "minute":
                dataList = towerOzoneMapper.queryMinuteData(startTime, endTime, stationName);
                break;
            case "hourly":
                dataList = towerOzoneMapper.queryHourlyData(startTime, endTime, stationName);
                break;
            case "8hour":
                dataList = get8HourAverageAllData(startTime, endTime, stationName);
                break;
            case "daily":
                dataList = towerOzoneMapper.queryDailyData(startTime, endTime, stationName);
                break;
            default:
                throw new IllegalArgumentException("不支持的查询类型: " + queryType);
        }

        // 转换数据格式
        result = transformData(dataList, stationName, startTime, endTime, queryType);

        return result;
    }

    private List<Map<String, Object>> get8HourAverageAllData(LocalDateTime startTime, LocalDateTime endTime, String stationName) {
        List<Map<String, Object>> result = new ArrayList<>();

        for(LocalDateTime i = startTime.minusHours(7); i.isBefore(endTime.minusHours(6)); i = i.plusHours(1)){
            List<Map<String, Object>> data = towerOzoneMapper.query8HourlyData(i,i.plusHours(8),stationName);
            LocalDateTime time = i.plusHours(8);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00:00");
            String timeStr = time.format(formatter); // 将 LocalDateTime 转换为字符串
            for (Map<String, Object> item : data) {
                item.put("time", timeStr);
            }

//            System.out.println(data);
            result.addAll(data);
        }
        return result;
    }

    private Map<String, Object> transformData(List<Map<String, Object>> dataList, String stationName, LocalDateTime startTime, LocalDateTime endTime, String queryType) {
        // 获取站点的高度列表
        List<Integer> heights = STATION_HEIGHT_MAP.get(stationName);
        if (heights == null) {
            throw new IllegalArgumentException("未知站点: " + stationName);
        }

        // 将数据按时间分组
//        Map<String, List<Map<String, Object>>> groupedByTime = dataList.stream()
//                .collect(Collectors.groupingBy(data -> (String) data.get("time")));
        // 将数据按时间分组
        Map<String, List<Map<String, Object>>> groupedByTime = new HashMap<>();
        for (Map<String, Object> data : dataList) {
            // 检查 time 字段的类型
            Object timeObj = data.get("time");
            String time;
            if (timeObj instanceof Timestamp) {
                // 如果是 Timestamp 类型，转换为字符串
                time = ((Timestamp) timeObj).toLocalDateTime()
                        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            } else if (timeObj instanceof String) {
                // 如果是 String 类型，直接使用
                time = (String) timeObj;
            } else {
                throw new IllegalArgumentException("time 字段类型不支持: " + timeObj.getClass());
            }

            groupedByTime.computeIfAbsent(time, k -> new ArrayList<>()).add(data);
        }

        // 转换数据格式
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map.Entry<String, List<Map<String, Object>>> entry : groupedByTime.entrySet()) {
            String time = entry.getKey();
            List<Map<String, Object>> timeData = entry.getValue();

            // 初始化每个时间点的数据
            Map<String, Object> item = new HashMap<>();
            item.put("time", time);
            item.put("o3", new ArrayList<>(Collections.nCopies(heights.size(), null)));
            item.put("co", new ArrayList<>(Collections.nCopies(heights.size(), null)));
            item.put("so2", new ArrayList<>(Collections.nCopies(heights.size(), null)));
            item.put("no2", new ArrayList<>(Collections.nCopies(heights.size(), null)));
            item.put("rh", new ArrayList<>(Collections.nCopies(heights.size(), null)));
            item.put("temp", new ArrayList<>(Collections.nCopies(heights.size(), null)));
            item.put("wind1", new ArrayList<>(Collections.nCopies(heights.size(), null)));
            item.put("wdir1", new ArrayList<>(Collections.nCopies(heights.size(), null)));
            item.put("wind2", new ArrayList<>(Collections.nCopies(heights.size(), null)));
            item.put("wdir2", new ArrayList<>(Collections.nCopies(heights.size(), null)));
            item.put("ww2", new ArrayList<>(Collections.nCopies(heights.size(), null)));

            // 填充数据
            for (Map<String, Object> data : timeData) {
                String pointName = (String) data.get("pointName");
//                System.out.println(data);
                int height = Integer.parseInt(pointName.replaceAll("[^0-9]", "")); // 提取高度数字

                // 找到高度在固定高度列表中的索引
                int heightIndex = heights.indexOf(height);
                if (heightIndex != -1) {
                    // 将数据放入对应位置
                    ((List<Object>) item.get("o3")).set(heightIndex, data.get("o3"));
                    ((List<Object>) item.get("co")).set(heightIndex, data.get("co"));
                    ((List<Object>) item.get("so2")).set(heightIndex, data.get("so2"));
                    ((List<Object>) item.get("no2")).set(heightIndex, data.get("no2"));
                    ((List<Object>) item.get("rh")).set(heightIndex, data.get("rh"));
                    ((List<Object>) item.get("temp")).set(heightIndex, data.get("temp"));
                    ((List<Object>) item.get("wind1")).set(heightIndex, data.get("wind1"));
                    ((List<Object>) item.get("wdir1")).set(heightIndex, data.get("wdir1"));
                    ((List<Object>) item.get("wind2")).set(heightIndex, data.get("wind2"));
                    ((List<Object>) item.get("wdir2")).set(heightIndex, data.get("wdir2"));
                    ((List<Object>) item.get("ww2")).set(heightIndex, data.get("wdir2"));
                }
            }

            result.add(item);
        }

        // 构建最终返回结果
        Map<String, Object> resultData = new HashMap<>();
        resultData.put("Station", stationName);
        resultData.put("select_Time", Arrays.asList(
                startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
                endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
        ));
        resultData.put("select_leixing", queryType);
        resultData.put("high", heights);
        resultData.put("result", result);
//        System.out.println(resultData);

        return resultData;
    }

}

